home *** CD-ROM | disk | FTP | other *** search
/ Aminet 26 / Aminet 26 (1998)(GTI - Schatztruhe)[!][Aug 1998].iso / XiPaint / Developer / Modules / XiMulti.c < prev    next >
C/C++ Source or Header  |  1995-09-09  |  33KB  |  1,324 lines

  1. /* Last Change: Thomas /   3. August 1995  07:27:56 */
  2.  
  3. // Multipic Loader/Saver
  4. //+ "/****  System-Includes  ****/"
  5.  
  6. /****  System-Includes  ****/
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11.  
  12. #include <exec/exec.h>
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <exec/execbase.h>
  16. #include <exec/ports.h>
  17.  
  18. #include <clib/alib_protos.h>
  19.  
  20. #include <dos/dosextens.h>
  21. #include <dos/dostags.h>
  22.  
  23. #include <proto/exec.h>
  24. #include <proto/dos.h>
  25. #include <include:libraries/iffparse.h>
  26.  
  27. #include "libraries/multipic.h"
  28. #include "proto/multipic_lib.h"
  29.  
  30. #include "XiUser.h"
  31. //-
  32.  
  33. #define REQ_PIC_W 60
  34. #define REQ_PIC_H 60
  35. #define ID_MPIC MAKE_ID('M','P','I','C')
  36. //+ "union color{"
  37.  
  38. union color{
  39.         LONG c24;
  40.         UBYTE c8[4];
  41.         };
  42. //-
  43. #define RED 0
  44. #define GRN 1
  45. #define BLU 2
  46. #define KEY 3
  47.  
  48.  
  49. //+ "Prototypes"
  50. int main(int argc, char **argv);
  51. void WaitReply(struct MsgPort *ReplyPort, struct Message *WaitMsg);
  52. BOOL open_xi_project(UWORD *w, UWORD *h, ULONG **mem, char *name);
  53. void update_project(void);
  54. BOOL unlock_project(void);
  55. BOOL lock_project(UWORD *w, UWORD *h, ULONG **mem);
  56. BOOL get_brush_mem(UWORD w, UWORD h, ULONG **mem);
  57. void update_brush(UWORD w, UWORD h, ULONG *mem);
  58. BOOL make_minipic (ULONG *src, WORD swidth, WORD sheight,
  59.                    ULONG *dest, WORD dwidth, WORD dheight);
  60. WORD save_mpic (struct PicHandle *pichandle, char *filename, ULONG *memory, short width, short height, ULONG id);
  61. void get_xibrush(UWORD *w, UWORD *h, ULONG **mem);
  62. void get_pal(ULONG **mem);
  63. void put_pal(ULONG *mem);
  64. WORD load_palette (char *filename, ULONG *palette);
  65. WORD save_palette (char *filename, ULONG *palette);
  66.  
  67. WORD pic_info (char *filename, UWORD *width, UWORD *height);
  68. WORD load_picture (char *fname, UWORD w, UWORD h, ULONG *mem);
  69. struct PicHandle *open_mp_lib (char *filename, LONG mode);
  70. struct PicInfo *get_mp_info (struct PicHandle *pichandle);
  71. WORD save_brush (char *filename, UWORD w, UWORD h, ULONG *mem, ULONG depth, ULONG format);
  72. BOOL may_minipic(ULONG id);
  73. BOOL may_alpha(ULONG id);
  74.  
  75. void send_error(char *string);
  76. void set_gauge(void *box, WORD prozent);
  77. void *open_gauge(char *title);
  78.  
  79. //-
  80. //+ "Statical structs for dedecting"
  81. struct xi_ext_header info =
  82. {
  83.   "XIPAINT-EXTERNAL000",
  84.   3,2,
  85.   'L',
  86.   "Multipic_Loader",
  87.   "MacroSystem",
  88.   1,0,
  89.   1,0,0,0,0,0,
  90.   0,0,0,
  91. };
  92.  
  93. struct xi_ext_header info2 =
  94. {
  95.   "XIPAINT-EXTERNAL000",
  96.   3,2,
  97.   'S',
  98.   "DEEP",
  99.   "MacroSystem",
  100.   1,0,
  101.   1,0,0,0,0,0,
  102.   1,0,0,
  103. };
  104. struct xi_ext_header info3 =
  105. {
  106.   "XIPAINT-EXTERNAL000",
  107.   3,2,
  108.   'S',
  109.   "ILBM",
  110.   "MacroSystem",
  111.   1,0,
  112.   1,0,0,0,0,0,
  113.   1,0,0,
  114. };
  115. struct xi_ext_header info4 =
  116. {
  117.   "XIPAINT-EXTERNAL000",
  118.   3,2,
  119.   'S',
  120.   "PGM",
  121.   "MacroSystem",
  122.   1,0,
  123.   1,0,0,0,0,0,
  124.   0,0,0,
  125. };
  126. struct xi_ext_header info5 =
  127. {
  128.   "XIPAINT-EXTERNAL000",
  129.   3,2,
  130.   'S',
  131.   "PPM",
  132.   "MacroSystem",
  133.   1,0,
  134.   1,0,0,0,0,0,
  135.   0,0,0,
  136. };
  137. struct xi_ext_header info6 =
  138. {
  139.   "XIPAINT-EXTERNAL000",
  140.   3,2,
  141.   'S',
  142.   "SUNRASTER",
  143.   "MacroSystem",
  144.   1,0,
  145.   1,0,0,0,0,0,
  146.   0,0,0,
  147. };
  148. //-
  149. //+ "Globals"
  150. struct XiMessage XiMsg;     // Sorry - my Global ones ...
  151. char ProjName[80];
  152. struct io_pic io;
  153. struct MsgPort *XiUserPort, *XiReplyPort;
  154. struct MultiPicBase *MultiPicBase = NULL;
  155. //-
  156.  
  157. int main(int argc, char **argv)
  158. {
  159.   short i=1;
  160.  
  161.   memset(&io,0,sizeof(struct io_pic));
  162.   io.todo = 'P';    // New Project is default
  163.   strcpy(io.port,"xiuser.port");
  164.  
  165.   // Auswerten der Kommandozeile (natuerlich nicht sooo)
  166.   //+ "  strcpy(io.name,argv[1]);"
  167.  
  168.   strcpy(io.name,argv[1]);
  169.   while (i < argc)
  170.   {
  171.     if (stricmp(argv[i],"smooth") == 0)
  172.     {
  173.       io.jpegs = 1;
  174.       i++;
  175.     }
  176.  
  177.     if (stricmp(argv[i],"cmap") == 0)
  178.     {
  179.       io.ext.cmap = 1;
  180.       i++;
  181.     }
  182.  
  183.     if (stricmp(argv[i],"clut") == 0)
  184.     {
  185.       io.ext.clut = 1;
  186.       i++;
  187.     }
  188.  
  189.     else if (stricmp(argv[i],"palette") == 0)
  190.     {
  191.       io.todo = 'A';
  192.       i++;
  193.     }
  194.  
  195.     else if (stricmp(argv[i],"load") == 0)
  196.     {
  197.       io.ext.what = 'L';
  198.       i++;
  199.     }
  200.     else if (stricmp(argv[i],"save") == 0)
  201.     {
  202.       io.ext.what = 'S';
  203.       i++;
  204.     }
  205.  
  206.     else if (stricmp(argv[i],"minipic") == 0)
  207.     {
  208.       io.minipic = 1;
  209.       i++;
  210.     }
  211.  
  212.     else if (stricmp(argv[i],"name") == 0)
  213.     {
  214.       i++;
  215.       if (i < argc)
  216.       {
  217.         strcpy(io.name,argv[i]);
  218.         i++;
  219.       }
  220.       else
  221.       {
  222.         printf("Error No Parameter given\n");
  223.       }
  224.     }
  225.  
  226.     else if (stricmp(argv[i],"port") == 0)
  227.     {
  228.       i++;
  229.       if (i < argc)
  230.       {
  231.         strcpy(io.port,argv[i]);
  232.         i++;
  233.       }
  234.       else
  235.       {
  236.         printf("Error No Parameter given\n");
  237.       }
  238.     }
  239.     else if (stricmp(argv[i],"module") == 0)
  240.     {
  241.       i++;
  242.       if (i < argc)
  243.       {
  244.         strcpy(io.ext.format,argv[i]);
  245.         i++;
  246.       }
  247.       else
  248.       {
  249.         printf("Error No Parameter given\n");
  250.       }
  251.     }
  252.     else if (stricmp(argv[i],"brush") == 0)
  253.     {
  254.       i++;
  255.       if (i < argc)
  256.       {
  257.         io.brushnr = atoi(argv[i]);
  258.         io.todo = 'B';
  259.         i++;
  260.       }
  261.       else
  262.       {
  263.         printf("Error No Parameter given\n");
  264.       }
  265.     }
  266.     else if (stricmp(argv[i],"project") == 0)
  267.     {
  268.       i++;
  269.       if (i < argc)
  270.       {
  271.         strcpy(io.proname,argv[i]);
  272.         io.todo = 'L';
  273.         i++;
  274.       }
  275.       else
  276.       {
  277.         printf("Error No Parameter given\n");
  278.       }
  279.     }
  280.     else if (stricmp(argv[i],"depth") == 0)
  281.     {
  282.       i++;
  283.       if (i < argc)
  284.       {
  285.         io.depth = atoi(argv[i]);
  286.         i++;
  287.       }
  288.       else
  289.       {
  290.         printf("Error No Parameter given\n");
  291.       }
  292.     }
  293.     else if (stricmp(argv[i],"xdpi") == 0)
  294.     {
  295.       i++;
  296.       if (i < argc)
  297.       {
  298.         io.xdpi = atoi(argv[i]);
  299.         i++;
  300.       }
  301.       else
  302.       {
  303.         printf("Error No Parameter given\n");
  304.       }
  305.     }
  306.     else if (stricmp(argv[i],"ydpi") == 0)
  307.     {
  308.       i++;
  309.       if (i < argc)
  310.       {
  311.         io.ydpi = atoi(argv[i]);
  312.         i++;
  313.       }
  314.       else
  315.       {
  316.         printf("Error No Parameter given\n");
  317.       }
  318.     }
  319.  
  320.     else if (stricmp(argv[i],"loss") == 0)
  321.     {
  322.       i++;
  323.       if (i < argc)
  324.       {
  325.         io.jpegf = atoi(argv[i]);
  326.         i++;
  327.       }
  328.       else
  329.       {
  330.         printf("Error No Parameter given\n");
  331.       }
  332.     }
  333.     else
  334.     {
  335.       printf("Unknown command\n");
  336.       i++;
  337.     }
  338.   }
  339. //-
  340.  
  341. //+ "Initialisation"
  342.      /**  Find the User-Port  **/
  343.     if ( (XiUserPort = FindPort((UBYTE *)(io.port))) == NULL )
  344.     {
  345.       printf("Couldn't find User-Port, is XiPaint started?\n");
  346.       exit(40);
  347.     }
  348.  
  349.     // Reply-Port
  350.     if ( (XiReplyPort = CreatePort(NULL, 0)) == NULL )
  351.     {
  352.       printf("Couldn't create a Reply-Port!\n");
  353.       exit(40);
  354.     }
  355.  
  356.     //  Initialise the Message
  357.     memset(&XiMsg, 0, sizeof(struct XiMessage));
  358.     XiMsg.ExecMess.mn_Node.ln_Type = NT_MESSAGE;
  359.     XiMsg.ExecMess.mn_Node.ln_Pri = 0;
  360.     XiMsg.ExecMess.mn_Length = sizeof(struct XiMessage);
  361.     XiMsg.ExecMess.mn_ReplyPort = XiReplyPort;
  362.     XiMsg.Label = 0x12345678;                           /* Erkennungsmarke für XiPaint, sehr wichtig !!!! */
  363. //-
  364.  
  365.   //
  366.   // Action!
  367.   //
  368.  
  369.   // What is our work? (Load or Save or Scan ...)
  370.  
  371.   switch (io.ext.what)
  372.   {
  373.     UWORD w,h;             // Desired Format
  374.     ULONG *mem=NULL;           // To handle temporary
  375.     ULONG format;
  376.     char *name;
  377.     void *box;
  378.  
  379. //+ "Loading"
  380.  
  381.     case 'L':             // Load a ...
  382.       w = strlen(io.name);
  383.       while (w > 0)
  384.       {
  385.         w --;
  386.         if ( (io.name[w] == ':') || (io.name[w] == '/') )
  387.         {
  388.           name = &io.name[w+1];
  389.           break;
  390.         }
  391.       }
  392.       switch (io.todo)
  393.       {
  394.         case 'B':         // ... a Brush
  395.           if (pic_info(io.name,&w,&h) == 0)
  396.             goto Ende;
  397.           box = open_gauge("Multipic");
  398.           if ( (get_brush_mem(w,h,&mem)) == FALSE)
  399.           {
  400.             set_gauge(box,100);
  401.             goto Ende;
  402.           }
  403.           set_gauge(box,10);
  404.           if ( (load_picture(io.name,w,h,mem)) == FALSE)
  405.           {
  406.             set_gauge(box,100);
  407.             goto Ende;
  408.           }
  409.           set_gauge(box,80);
  410.           update_brush(w,h,mem);
  411.           set_gauge(box,100);
  412.           break;
  413.         case 'L':         // ... a Pic into a project
  414.           box = open_gauge("Multipic");
  415.           strcpy(ProjName,io.proname);
  416.           if ((lock_project(&w,&h,&mem)) == FALSE)
  417.           {
  418.             set_gauge(box,100);
  419.             goto Ende;
  420.           }
  421.           set_gauge(box,10);
  422.           load_picture(io.name,w,h,mem);
  423.           set_gauge(box,100);
  424.           update_project();   // Show the work
  425.           unlock_project();   // XiPaint can work
  426.           break;
  427.         case 'P':         // ... a new project
  428.           if (pic_info(io.name,&w,&h) == 0)
  429.             goto Ende;
  430.           // Open Xipaint Project to get memory
  431.           box = open_gauge("Multipic");
  432.           if (open_xi_project(&w,&h,&mem,name) == FALSE)  // No mem in XiPaint, sorry
  433.           {
  434.             set_gauge(box,100);
  435.             send_error("Couldn't open XiPaint Window.\nSorry!");
  436.             goto Ende;
  437.           }
  438.           // Load the picture into the memory
  439.           set_gauge(box,10);
  440.           load_picture(io.name,w,h,mem);
  441.           update_project();   // Show the work
  442.           set_gauge(box,80);
  443.           unlock_project();   // XiPaint can work
  444.           set_gauge(box,100);
  445.           break;
  446.         case 'A':  // ... a palette
  447.           get_pal(&mem);
  448.           load_palette(io.name,mem);
  449.           put_pal(mem);
  450.           break;
  451.       }
  452.       break;
  453. //-
  454. //+ "Saving"
  455.     case 'S':
  456.       strcpy(ProjName,io.proname);
  457.  
  458.       if (io.todo == 'L')
  459.         io.todo= 'P';
  460.  
  461.       // First we will look, which format to save
  462.       if (stricmp(io.ext.format,"DEEP") == 0)
  463.         format = PFT_DEEP;
  464.       else if (stricmp(io.ext.format,"ILBM") == 0)
  465.         format = PFT_ILBM;
  466.       else if (stricmp(io.ext.format,"PGM") == 0)
  467.         format = PFT_PGM;
  468.       else if (stricmp(io.ext.format,"PPM") == 0)
  469.         format = PFT_PPM;
  470.       else if (stricmp(io.ext.format,"SUNRASTER") == 0)
  471.         format = PFT_SUNRASTER;
  472.       else
  473.       {
  474.         send_error("Unsupported Format\n");
  475.         goto Ende;
  476.       }
  477.  
  478.                   // Save a ...
  479.       switch (io.todo)
  480.       {
  481.         case 'B':         // ... a Brush
  482.           get_xibrush(&w, &h, &mem);  // Got it
  483.           // if (io.ext.alpha)
  484.           if (io.depth == 32)
  485.           {
  486.             if (may_alpha(format))
  487.               save_brush(io.name,w,h,mem,32,format);
  488.             else
  489.               save_brush(io.name,w,h,mem,24,format);
  490.           }
  491.           else
  492.             save_brush(io.name,w,h,mem,24,format);
  493.           break;
  494.         case 'P':         // ... a Pic from a project
  495.           if ((lock_project(&w, &h, &mem))==FALSE)
  496.           {
  497.             goto Ende;
  498.           }
  499.  
  500.           if (io.ext.alpha)
  501.           {
  502.             if (may_alpha(format))
  503.               save_brush(io.name,w,h,mem,32,format);
  504.             else
  505.               save_brush(io.name,w,h,mem,24,format);
  506.           }
  507.           else
  508.             save_brush(io.name,w,h,mem,24,format);
  509.           unlock_project();            // Give it back
  510.           break;
  511.         case 'A':
  512.           get_pal(&mem);
  513.           save_palette(io.name,mem);
  514.           put_pal(mem);
  515.           break;
  516.       }
  517.       break;
  518. //-
  519. //+ "Filtering"
  520.     case 'F':             // Filter a ...
  521.       switch (io.todo)
  522.       {
  523.         case 'B':         // ... Brush
  524.           break;
  525.         case 'P':         // ... Project
  526.           break;
  527.       }
  528.       break;
  529. //-
  530. //+ "Printing"
  531.     case 'P':             // Print a ...
  532.       switch (io.todo)
  533.       {
  534.         case 'B':         // ... Brush
  535.           break;
  536.         case 'P':         // ... Project
  537.           break;
  538.       }
  539.       break;
  540. //-
  541. //+ "Scanning"
  542.     case 'C':             // Scan a ...
  543.       switch (io.todo)
  544.       {
  545.         case 'B':         // ... Brush
  546.           break;
  547.         case 'P':         // ... Project
  548.           break;
  549.       }
  550.       break;
  551. //-
  552.     default:
  553.     break;
  554.   }
  555.  
  556.   // End-Work
  557.  Ende:
  558.     DeletePort(XiReplyPort);
  559. }
  560.  
  561. // Waits till WaitMsg comes from Reply-port
  562. //+ "void WaitReply(struct MsgPort *ReplyPort, struct Message *WaitMsg)"
  563.  
  564. void WaitReply(struct MsgPort *ReplyPort, struct Message *WaitMsg)
  565. {
  566.   struct Message *OkMsg;
  567.   BOOL Loop=TRUE;
  568.  
  569.   while(Loop)
  570.   {
  571.     WaitPort(ReplyPort);
  572.     while( OkMsg = GetMsg(ReplyPort) )
  573.     {
  574.       if ( OkMsg == WaitMsg )
  575.         Loop = FALSE;
  576.     }
  577.   }
  578. }
  579. //-
  580.  
  581. //
  582. // Functions to handle everything easier with XiPaint MsgPort
  583. //
  584.  
  585. //+ "BOOL open_xi_project(UWORD *w, UWORD *h, ULONG **mem)"
  586.  
  587. BOOL open_xi_project(UWORD *w, UWORD *h, ULONG **mem, char *name)
  588. {
  589.   sprintf(ProjName, "____%s",name);                      /* Puffer initialisieren */
  590.  
  591.   XiMsg.Command = XI_NEW_PROJECT;                             /* Kommando ausfüllen */
  592.   XiMsg.ProjectName = ProjName;                               /* Name des Projekts */
  593.   XiMsg.Width = (short)*w;                                          /* Größe des Projekts */
  594.   XiMsg.Height = (short)*h;
  595.  
  596.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  597.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  598.  
  599.   if ( XiMsg.Success == TRUE )                        /* Aktion war erfolgreich */
  600.   {
  601.     *mem = (ULONG *)XiMsg.Memory;                               /* Auswerten der Rückgabewerte */
  602.     *w = (UWORD)XiMsg.Width;                    /* Wichtig: Größe kann sich geändert haben (größer geworden) */
  603.     *h = (UWORD)XiMsg.Height;                  /* daher ist ein Übernehem der neuen Größe unbedingt erforderlich !! */
  604.   }
  605.   else
  606.   {
  607.     printf("Couldn't open Projekt '%s'\n", ProjName);
  608.     return(FALSE);
  609.   }
  610. }
  611. //-
  612. //+ "void send_error(char *string)"
  613.  
  614. void send_error(char *string)
  615. {
  616.   XiMsg.Command = XI_PUT_ERROR;                             /* Kommando ausfüllen */
  617.   XiMsg.ProjectName = ProjName;                               /* Name des Projekts */
  618.   XiMsg.Memory = string;
  619.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  620.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  621. }
  622. //-
  623. //+ "void *open_gauge(char *title)"
  624.  
  625. void *open_gauge(char *title)
  626. {
  627.   XiMsg.Command = XI_OPEN_GAUGE;                             /* Kommando ausfüllen */
  628.   XiMsg.Memory = title;
  629.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  630.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  631.   return(XiMsg.Memory);
  632. }
  633. //-
  634. //+ "void set_gauge(void *box, WORD prozent)"
  635.  
  636. void set_gauge(void *box, WORD prozent)
  637. {
  638.   XiMsg.Command = XI_MOVE_GAUGE;                             /* Kommando ausfüllen */
  639.   XiMsg.Memory = box;
  640.   XiMsg.Width = prozent;
  641.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  642.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  643. }
  644. //-
  645. //+ "void update_project(void)"
  646.  
  647. void update_project(void)
  648. {
  649.   XiMsg.Command = XI_UPDATE_PROJECT;                      /* Kommando ausfüllen */
  650.   XiMsg.ProjectName = ProjName;                           /* ProjName-Variable durch Open-Call auf Namen mit Kennung geändert  !!!! */
  651.   PutMsg(XiUserPort, (struct Message *)&XiMsg);           /* Message absenden */
  652.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);       /* Warten auf Reply, siehe Fkt. unten, Erfolgscheck nicht notwendig */
  653. }
  654. //-
  655. //+ "BOOL unlock_project(void)"
  656.  
  657. BOOL unlock_project(void)
  658. {
  659.   XiMsg.Command = XI_UNLOCK_PROJECT;                          /* Kommando ausfüllen */
  660.   XiMsg.ProjectName = ProjName;                               /* Name des Projekts */
  661.  
  662.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  663.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  664.  
  665.   if ( XiMsg.Success == FALSE )                        /* Aktion war erfolgreich (sollte immer sein...) */
  666.   {
  667.     char buf[80];
  668.     sprintf(buf,"Couldn't unlock '%s'!\n", ProjName);
  669.     send_error(buf);
  670.     return(FALSE);
  671.   }
  672.   return(TRUE);
  673. }
  674. //-
  675. //+ "BOOL lock_project(UWORD *w, UWORD *h, ULONG **mem)"
  676.  
  677. BOOL lock_project(UWORD *w, UWORD *h, ULONG **mem)
  678. {
  679.   XiMsg.Command = XI_LOCK_PROJECT;                            /* Kommando ausfüllen */
  680.   XiMsg.ProjectName = ProjName;                               /* Name des Projekts */
  681.  
  682.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  683.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  684.  
  685.   if ( XiMsg.Success == TRUE )                        /* Aktion war erfolgreich */
  686.   {
  687.     *mem = (ULONG *)XiMsg.Memory;                               /* Auswerten der Rückgabewerte */
  688.     *w = XiMsg.Width;
  689.     *h = XiMsg.Height;
  690.   }
  691.   else
  692.   {
  693.     char buf[80];
  694.     sprintf(buf,"Couldn't lock '%s'!\n", ProjName);
  695.     send_error(buf);
  696.     return(FALSE);
  697.   }
  698.   return(TRUE);
  699. }
  700. //-
  701. //+ "BOOL get_brush_mem(UWORD w, UWORD h, ULONG **mem)"
  702.  
  703. BOOL get_brush_mem(UWORD w, UWORD h, ULONG **mem)
  704. {
  705.   XiMsg.Command = XI_NEW_BRUSH;                             /* Kommando ausfüllen */
  706.   XiMsg.Width  = w;                                          /* Größe des Projekts */
  707.   XiMsg.Height = h;
  708.  
  709.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  710.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  711.  
  712.   if ( XiMsg.Success == TRUE )                        /* Aktion war erfolgreich */
  713.   {
  714.     *mem = (ULONG *)XiMsg.Memory;
  715.   }
  716.   else
  717.   {
  718.     send_error("No memory for brush\nfrom XiPaint!\n");
  719.     return(FALSE);
  720.   }
  721.   return(TRUE);
  722. }
  723. //-
  724. //+ "void update_brush(UWORD w, UWORD h, ULONG *mem)"
  725.  
  726. void update_brush(UWORD w, UWORD h, ULONG *mem)
  727. {
  728.    // Brush in Liste aufnehmen
  729.  
  730.    XiMsg.Width  = w;                                          /* Größe des Projekts */
  731.    XiMsg.Height = h;
  732.    XiMsg.Memory = (char *)mem;
  733.  
  734.    XiMsg.Command = XI_UPDATE_BRUSH;                      /* Kommando ausfüllen */
  735.    PutMsg(XiUserPort, (struct Message *)&XiMsg);           /* Message absenden */
  736.    WaitReply(XiReplyPort, (struct Message *)&XiMsg);       /* Warten auf Reply, siehe Fkt. unten, Erfolgscheck nicht notwendig */
  737. }
  738. //-
  739. //+ "void get_xibrush(UWORD *w, UWORD *h, ULONG **mem)"
  740.  
  741. void get_xibrush(UWORD *w, UWORD *h, ULONG **mem)
  742. {
  743.   XiMsg.Command = XI_GET_BRUSH;                            /* Kommando ausfüllen */
  744.  
  745.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  746.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  747.  
  748.   if ( XiMsg.Success == TRUE )                        /* Aktion war erfolgreich */
  749.   {
  750.     *mem = (ULONG *)XiMsg.Memory;                               /* Auswerten der Rückgabewerte */
  751.     *w = XiMsg.Width;
  752.     *h = XiMsg.Height;
  753.   }
  754.   else
  755.   {
  756.     send_error("Couldn't lock Brush\n");
  757.   }
  758. }
  759. //-
  760. //+ "void get_pal(ULONG **mem)"
  761.  
  762. void get_pal(ULONG **mem)
  763. {
  764.   XiMsg.Command = XI_GET_PALETTE;                            /* Kommando ausfüllen */
  765.  
  766.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  767.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  768.  
  769.   if ( XiMsg.Success == TRUE )                        /* Aktion war erfolgreich */
  770.   {
  771.     *mem = (ULONG *)XiMsg.Memory;                               /* Auswerten der Rückgabewerte */
  772.   }
  773.   else
  774.   {
  775.     printf("Couldn't lock '%s'!\n", ProjName);
  776.     exit(0);
  777.   }
  778. }
  779. //-
  780. //+ "void put_pal(ULONG *mem);"
  781.  
  782. void put_pal(ULONG *mem)
  783. {
  784.   XiMsg.Command = XI_UPDATE_PALETTE;                            /* Kommando ausfüllen */
  785.  
  786.   PutMsg(XiUserPort, (struct Message *)&XiMsg);               /* Message absenden */
  787.   WaitReply(XiReplyPort, (struct Message *)&XiMsg);           /* Warten auf Reply, siehe Fkt. unten */
  788.  
  789. }
  790. //-
  791.  
  792. //
  793. // Functions to handle everything easier with multipic
  794. //
  795. //+ "  WORD pic_info (char *filename, UWORD *width, UWORD *height)"
  796.  
  797. WORD pic_info (char *filename, UWORD *width, UWORD *height)
  798. {
  799.   struct PicInfo *Info;
  800.   struct PicHandle *mypichandle;
  801.   WORD rvalue;
  802.  
  803.   mypichandle = open_mp_lib (filename, MPMODE_LOAD);
  804.   if (mypichandle)
  805.   {
  806.     Info = get_mp_info (mypichandle);
  807.     if (Info)
  808.     {
  809.       *width = Info->pi_Width;
  810.       *height = Info->pi_Height;
  811.       rvalue = 1;
  812.     }
  813.     else
  814.     {
  815.       rvalue = 0;
  816.     }
  817.     MP_Close (mypichandle);
  818.     CloseLibrary((struct Library *)MultiPicBase);
  819.   }
  820.   else
  821.   {
  822.     rvalue = 0;
  823.   }
  824.   return (rvalue);
  825. }
  826. //-
  827. //+ "  struct PicHandle *open_mp_lib (char *filename, LONG mode)"
  828.  
  829. struct PicHandle *open_mp_lib (char *filename, LONG mode)
  830. {
  831.   struct PicHandle *mypichandle;
  832.  
  833.   if (MultiPicBase == NULL)
  834.   {
  835.     if ((MultiPicBase = (struct MultiPicBase *) OpenLibrary ("multipic.library", 0L)) == NULL)
  836.     {
  837.       return (NULL);
  838.     }
  839.   }
  840.   mypichandle = MP_Open (filename, mode);
  841.  
  842.   if (mypichandle == NULL)
  843.   {
  844.     /* printf ("MP_Open schlug fehl\n"); */
  845.     CloseLibrary((struct Library *)MultiPicBase);
  846.     return (NULL);
  847.   }
  848.   return (mypichandle);
  849. }
  850. //-
  851. //+ "  struct PicInfo *get_mp_info (struct PicHandle *pichandle)"
  852.  
  853. struct PicInfo *get_mp_info (struct PicHandle *pichandle)
  854. {
  855.   struct PicInfo *Info = NULL;
  856.  
  857.   if (pichandle)
  858.     Info = MP_Info (pichandle);
  859.  
  860.   if (Info == NULL)
  861.   {
  862.     printf("Error: no Info\n");
  863.     return NULL;
  864.   }
  865.   return (Info);
  866. }
  867. //-
  868. //+ "  WORD load_picture (char *fname, UWORD w, UWORD h, ULONG *mem)"
  869.  
  870. WORD load_picture (char *fname, UWORD w, UWORD h, ULONG *mem)
  871. {
  872.   struct TagItem mytagitem[12];
  873.   ULONG error;
  874.   WORD rvalue;
  875.   struct PicInfo *Info;
  876.   struct PicHandle *mypichandle;
  877.   WORD width, height;
  878.   ULONG cc=0;
  879.  
  880.   if (mem == NULL)
  881.   {
  882.     send_error("No Memory for loading\n");
  883.     return(FALSE);
  884.   }
  885.  
  886.   mypichandle = open_mp_lib (fname, MPMODE_LOAD);
  887.   if (mypichandle)
  888.   {
  889.     Info = get_mp_info (mypichandle);
  890.  
  891.     if (Info)
  892.     {
  893.       if (Info->pi_Type == PFT_UNKNOWN)                                        /* Multipic ist fehlgeschlagen */
  894.       {
  895.         MP_Close (mypichandle);
  896.         send_error("Unknown format");                                              /* Check for Errors */
  897.         return(FALSE);
  898.       }
  899.       else
  900.       {
  901.         width = Info->pi_Width;
  902.         if (width > w)
  903.           width = w;
  904.  
  905.         height = Info->pi_Height;
  906.         if (height > h)
  907.           height = h;
  908.  
  909.         if (io.ext.clut)
  910.           cc = 0x02;
  911.         if (io.ext.cmap)
  912.           cc |= 0x01;
  913.  
  914.         mytagitem[0].ti_Tag = BAT_Inc;
  915.         mytagitem[0].ti_Data = 4;                                              /* 4 Bytes pro Pixel */
  916.         mytagitem[1].ti_Tag = BAT_Width;                                       /* Falls Bild kleiner oder größer als Speicher */
  917.         mytagitem[1].ti_Data = width;
  918.         mytagitem[2].ti_Tag = BAT_Mod;
  919.         mytagitem[2].ti_Data = w * 4;
  920.         mytagitem[3].ti_Tag = BAT_DefaultAlphaValue;
  921.         mytagitem[3].ti_Data = 255;                                            /* (Füllmuster) Ohne Alpha = 0 */
  922.         mytagitem[4].ti_Tag = BAT_MergePalette;
  923.         mytagitem[4].ti_Data = cc;
  924.         mytagitem[5].ti_Tag = TAG_DONE;
  925.  
  926.         MP_SetBufferAttrs (mypichandle, mytagitem);
  927.  
  928.         error = MP_Read (mypichandle, (UBYTE *) mem, (UBYTE *) (mem) + 1, (UBYTE *) (mem) + 2, (UBYTE *) (mem) + 3, height);
  929.  
  930.         if (!error)
  931.         {
  932.           send_error("Error in Reading\n");                                            /* Check for Errors */
  933.           rvalue = FALSE;
  934.         }
  935.         else
  936.         {
  937.           rvalue = TRUE;
  938.         }
  939.       }
  940.     }
  941.     else
  942.     {
  943.       /* kein Info bekommen */
  944.       rvalue = FALSE;
  945.     }
  946.     MP_Close (mypichandle);
  947.     CloseLibrary((struct Library *)MultiPicBase);
  948.   }
  949.  
  950.   return (rvalue);
  951. }
  952. //-
  953.  
  954.  
  955. //+ "WORD save_brush (char *filename, UWORD w, UWORD h, ULONG *mem, ULONG depth, ULONG format)"
  956.  
  957. WORD save_brush (char *filename, UWORD w, UWORD h, ULONG *mem, ULONG depth, ULONG format)
  958. {
  959.   struct TagItem mytagitem[12];
  960.   ULONG error;
  961.   struct PicHandle *mypichandle;
  962.  
  963.   mypichandle = open_mp_lib (filename, MPMODE_SAVE);
  964.  
  965.   if (mypichandle)
  966.   {
  967.  
  968.     mytagitem[0].ti_Tag = IAT_Type;
  969.     mytagitem[0].ti_Data = format;        // PFT_DEEP;     // Here the format
  970.     mytagitem[1].ti_Tag = IAT_Width;
  971.     mytagitem[1].ti_Data = w;
  972.     mytagitem[2].ti_Tag = IAT_Height;
  973.     mytagitem[2].ti_Data = h;
  974.     mytagitem[3].ti_Tag = IAT_Depth;
  975.     mytagitem[3].ti_Data = depth;           // 24 / 32;
  976.     mytagitem[4].ti_Tag = TAG_DONE;
  977.  
  978.     MP_SetImageAttrs (mypichandle, mytagitem);
  979.  
  980.     mytagitem[0].ti_Tag = BAT_Inc;
  981.     mytagitem[0].ti_Data = 4;                                                  /* 4 Bytes pro Pixel */
  982.     mytagitem[1].ti_Tag = BAT_Width;                                           /* Falls Bild kleiner oder größer als Speicher */
  983.     mytagitem[1].ti_Data = w;
  984.     mytagitem[2].ti_Tag = BAT_Mod;
  985.     mytagitem[2].ti_Data = w * 4;
  986.     mytagitem[3].ti_Tag = TAG_DONE;
  987.  
  988.     MP_SetBufferAttrs (mypichandle, mytagitem);
  989.  
  990.     if (io.minipic)
  991.       save_mpic (mypichandle, filename, mem, w, h,format);
  992.  
  993.     error = MP_Write (mypichandle, (UBYTE *) mem, (UBYTE *) mem + 1, (UBYTE *) mem + 2, (UBYTE *) mem + 3, h);
  994.     if (!error)
  995.     {
  996.       send_error("Error in Writing\n");
  997.     }
  998.     MP_Close (mypichandle);
  999.     CloseLibrary((struct Library *)MultiPicBase);
  1000.   }
  1001.   return (1);
  1002. }
  1003. //-
  1004. //+ "BOOL make_minipic (ULONG *src, WORD swidth, WORD sheight,"
  1005. BOOL make_minipic (ULONG *src, WORD swidth, WORD sheight,
  1006.                    ULONG *dest, WORD dwidth, WORD dheight)
  1007. {
  1008.   WORD k,offx = -1, offy = -1;
  1009.   UWORD sizeX, sizeY;
  1010.   double facd,facs;
  1011.  
  1012.   if (dest == NULL)
  1013.     return (FALSE);
  1014.   if (dwidth == 0)
  1015.     return (FALSE);
  1016.   if (dheight == 0)
  1017.     return (FALSE);
  1018.  
  1019.   memset (dest, (size_t) (dwidth * dheight * sizeof (ULONG)), 0);     /* Schwarzer Rand */
  1020.  
  1021.   if ( (src == NULL) || (swidth == 0) || (sheight == 0) )
  1022.     return (TRUE);
  1023.  
  1024.   /* printf("sw:%d sh:%d, dw:%d, dh:%d\n",swidth, sheight, dwidth, dheight); */
  1025.  
  1026.   if (swidth <= dwidth)
  1027.     offx = (dwidth - swidth) / 2;                /* Offset in Breite Bestimmen */
  1028.  
  1029.   if (sheight <= dheight)                         /* Offset in Höhe */
  1030.     offy = (dheight - sheight) / 2;
  1031.  
  1032.   if ( (offx > -1) && (offy > -1) )           /* Paßt komplett ins Bild */
  1033.     {
  1034.     for (k = 0; k < sheight; k++)
  1035.       {
  1036.       ULONG *B1Buffer, *End;
  1037.  
  1038.       for (B1Buffer = dest + ( (k+offy) * dwidth + offx), End = B1Buffer + swidth;
  1039.            B1Buffer < End; B1Buffer++, src++)
  1040.         {
  1041.           *B1Buffer = *src;
  1042.         }
  1043.       }
  1044.       return(TRUE);
  1045.     }
  1046.  
  1047.   facs = (double)swidth / (double)sheight;
  1048.   facd = (double)dwidth / (double)dheight;
  1049.  
  1050.   if (facs  > facd)
  1051.   {
  1052.     facd = (double)swidth / (double)dwidth;
  1053.     sizeY = (UWORD)((double)sheight / facd);
  1054.     offy = (dheight - sizeY) / 2;
  1055.  
  1056.     sizeX = dwidth * 1000 / swidth;
  1057.     sizeY = sizeY * 1000 / sheight;
  1058.  
  1059.     dheight= dheight - 2*offy - 1;
  1060.  
  1061.     for (k = 0; k < dheight; k++)
  1062.     {
  1063.       ULONG *B1Buffer, *B2Buffer, *End;
  1064.       UWORD index;
  1065.  
  1066.       for (B1Buffer = dest + ((k+offy) * dwidth),
  1067.          B2Buffer = src + (((k * 1000) / sizeY) * swidth),
  1068.          End = B1Buffer + dwidth,
  1069.          index = 0;
  1070.          B1Buffer < End; B1Buffer++, index++)
  1071.       {
  1072.         *B1Buffer = *(B2Buffer + index * 1000 / sizeX);
  1073.       }
  1074.     }
  1075.   }
  1076.   else
  1077.   {
  1078.     WORD neww;
  1079.  
  1080.     facd = (double)sheight / (double)dheight;
  1081.     sizeX = (UWORD)((double)swidth / facd);
  1082.     offx = (dwidth - sizeX) / 2;
  1083.  
  1084.     sizeX = sizeX * 1000 / swidth;
  1085.     sizeY = dheight * 1000 / sheight;
  1086.  
  1087.     neww = dwidth - 2 * offx;
  1088.  
  1089.     for (k = 0; k < dheight; k++)
  1090.     {
  1091.       ULONG *B1Buffer, *B2Buffer, *End;
  1092.       UWORD index;
  1093.  
  1094.       for (B1Buffer = dest + (k * dwidth)+offx,
  1095.          B2Buffer = src + (((k * 1000) / sizeY) * swidth),
  1096.          End = B1Buffer + neww,
  1097.          index = 0;
  1098.          B1Buffer < End; B1Buffer++, index++)
  1099.       {
  1100.         *B1Buffer = *(B2Buffer + index * 1000 / sizeX);
  1101.       }
  1102.     }
  1103.   }
  1104.  
  1105. #if 0
  1106.   sizeX = dwidth * 1000 / swidth;
  1107.   sizeY = dheight * 1000 / sheight;
  1108.  
  1109.   for (k = 0; k < dheight; k++)
  1110.   {
  1111.     ULONG *B1Buffer, *B2Buffer, *End;
  1112.     UWORD index;
  1113.  
  1114.     for (B1Buffer = dest + (k * dwidth),
  1115.          B2Buffer = src + (((k * 1000) / sizeY) * swidth),
  1116.          End = B1Buffer + dwidth,
  1117.          index = 0;
  1118.          B1Buffer < End; B1Buffer++, index++)
  1119.     {
  1120.       *B1Buffer = *(B2Buffer + index * 1000 / sizeX);
  1121.     }
  1122.   }
  1123. #endif
  1124.  
  1125.   return (TRUE);
  1126. }
  1127. //-
  1128. //+ "WORD save_mpic (struct PicHandle *pichandle, char *filename, ULONG *memory, short width, short height, ULONG id)"
  1129.  
  1130. WORD save_mpic (struct PicHandle *pichandle, char *filename, ULONG *memory, short width, short height, ULONG id)
  1131. {
  1132.   BOOL FileMini = TRUE;
  1133.   UBYTE *mpmem;
  1134.   short mpwidth, mpheight;
  1135.   WORD *sizearray;
  1136.  
  1137.   mpwidth = REQ_PIC_W;
  1138.   mpheight = REQ_PIC_H;
  1139.  
  1140.   if (mpmem = calloc ((size_t) (mpwidth * mpheight * sizeof (ULONG) + sizeof (WORD) * 4),1))
  1141.   {
  1142.     sizearray = (WORD *) mpmem;
  1143.  
  1144.     sizearray[0] = mpwidth;
  1145.     sizearray[1] = mpheight;
  1146.     sizearray[2] = 4;
  1147.     sizearray[3] = 2;
  1148.  
  1149.     make_minipic (memory, width, height, (ULONG *) (mpmem + sizeof (WORD) * 4), mpwidth, mpheight);
  1150.   }
  1151.   else
  1152.     return 0;
  1153.  
  1154.   if (pichandle)
  1155.   {
  1156.     if (may_minipic(id) == TRUE)
  1157.     {
  1158.       if (MP_WriteProp (pichandle, mpmem, ID_MPIC,
  1159.                           (ULONG) (mpwidth * mpheight * sizeof (ULONG) + sizeof (WORD) * 4), 1))
  1160.          FileMini = FALSE;
  1161.     }
  1162.   }
  1163.  
  1164.   if (FileMini)
  1165.   {
  1166.     strcat (filename,".MPIC");
  1167.  
  1168.     save_brush (filename, mpwidth, mpheight, (ULONG *)(mpmem + sizeof (WORD) * 4), 24,PFT_DEEP);
  1169.   }
  1170.  
  1171.   free (mpmem);
  1172.   return 1;
  1173. }
  1174. //-
  1175.  
  1176. //+ "BOOL may_alpha(ULONG id)"
  1177.  
  1178. BOOL may_alpha(ULONG id)
  1179. {
  1180.   struct FormatInfo *fi;
  1181.  
  1182.   if ((MultiPicBase = (struct MultiPicBase *) OpenLibrary ("multipic.library", 0L)) == NULL)
  1183.   {
  1184.     printf("No multipic.library\n");
  1185.     exit(23);
  1186.   }
  1187.  
  1188.   fi = MP_NextFormatInfo (NULL, 0L, 0L);
  1189.   while (fi)
  1190.   {
  1191.     if (fi->fi_Type == id)
  1192.     {
  1193.       if ((fi->fi_Flags & FIF_SAVE) && (fi->fi_Flags & FIF_ALPHA) )
  1194.         return(TRUE);
  1195.       else
  1196.         return(FALSE);
  1197.     }
  1198.     fi = MP_NextFormatInfo (fi, 0L, 0L);
  1199.   }
  1200.   CloseLibrary((struct Library *)MultiPicBase);
  1201. }
  1202. //-
  1203. //+ "BOOL may_minipic(ULONG id)"
  1204.  
  1205. BOOL may_minipic(ULONG id)
  1206. {
  1207.   struct FormatInfo *fi;
  1208.  
  1209.   if ((MultiPicBase = (struct MultiPicBase *) OpenLibrary ("multipic.library", 0L)) == NULL)
  1210.   {
  1211.     printf("No multipic.library\n");
  1212.     exit(23);
  1213.   }
  1214.  
  1215.   fi = MP_NextFormatInfo (NULL, 0L, 0L);
  1216.   while (fi)
  1217.   {
  1218.     if (fi->fi_Type == id)
  1219.     {
  1220.       if ((fi->fi_Flags & FIF_SAVE) && (fi->fi_Flags & FIF_PROPERTY) )
  1221.         return(TRUE);
  1222.       else
  1223.         return(FALSE);
  1224.     }
  1225.     fi = MP_NextFormatInfo (fi, 0L, 0L);
  1226.   }
  1227.   CloseLibrary((struct Library *)MultiPicBase);
  1228. }
  1229. //-
  1230.  
  1231. //+ "WORD load_palette (char *filename, ULONG *palette)"
  1232.  
  1233. WORD load_palette (char *filename, ULONG *palette)
  1234. {
  1235.   UBYTE *error;
  1236.   struct PicInfo *Info;
  1237.   struct PicHandle *mypichandle;
  1238.   union color *pal;
  1239.  
  1240.   pal = (union color *)palette;
  1241.   mypichandle = open_mp_lib (filename, MPMODE_LOAD);
  1242.  
  1243.   Info = get_mp_info (mypichandle);
  1244.  
  1245.   if (Info)
  1246.   {
  1247.  
  1248.     if (Info->pi_CMapEntries > 0)
  1249.     {
  1250.       error = MP_ReadPalette (mypichandle, NULL, PT_RGB);                      /* Kein Buffer angelegt */
  1251.  
  1252.       if (error)
  1253.       {
  1254.         WORD i;
  1255.  
  1256.         for (i = 0; i < Info->pi_CMapEntries; i++)
  1257.         {
  1258.           pal[i].c8[RED] = error[i * 3];
  1259.           pal[i].c8[GRN] = error[i * 3 + 1];
  1260.           pal[i].c8[BLU] = error[i * 3 + 2];
  1261.         }
  1262.       }
  1263.       else
  1264.       {
  1265.         printf("Error loading palette\n");
  1266.       }
  1267.     }
  1268.     else
  1269.      printf("Error loading palette, no info-chunk\n");
  1270.   }
  1271.     MP_Close (mypichandle);
  1272.     CloseLibrary((struct Library *)MultiPicBase);
  1273.   return 1;
  1274. }
  1275. //-
  1276. //+ "WORD save_palette (char *filename, ULONG *palette)"
  1277.  
  1278. WORD save_palette (char *filename, ULONG *palette)
  1279. {
  1280.   struct TagItem mytagitem[12];
  1281.   BOOL error;
  1282.   struct PicHandle *mypichandle;
  1283.   UBYTE *mymem;
  1284.   union color *pal;
  1285.  
  1286.   pal = (union color *)palette;
  1287.  
  1288.   mypichandle = open_mp_lib (filename, MPMODE_SAVE);
  1289.  
  1290.   if (mypichandle)
  1291.   {
  1292.  
  1293.     mytagitem[0].ti_Tag = IAT_Depth;
  1294.     mytagitem[0].ti_Data = 8;                                                  /* 24 / 32; */
  1295.     mytagitem[1].ti_Tag = TAG_DONE;
  1296.  
  1297.     MP_SetImageAttrs (mypichandle, mytagitem);
  1298.  
  1299.     mymem = AllocVec (256 * 3, MEMF_ANY | MEMF_CLEAR);
  1300.     if (mymem)
  1301.     {
  1302.       WORD i;
  1303.  
  1304.       for (i = 0; i < 256; i++)
  1305.       {
  1306.         mymem[i * 3] = pal[i].c8[RED];
  1307.         mymem[i * 3 + 1] = pal[i].c8[GRN];
  1308.         mymem[i * 3 + 2] = pal[i].c8[BLU];
  1309.       }
  1310.       error = MP_WritePalette (mypichandle, mymem, PT_RGB);
  1311.       if (!error)
  1312.         printf ("Error in Writing palette\n");
  1313.       FreeVec (mymem);
  1314.     }
  1315.   }
  1316.  
  1317.   MP_Close (mypichandle);
  1318.   CloseLibrary((struct Library *)MultiPicBase);
  1319.   return 1;
  1320. }
  1321. //-
  1322.  
  1323.  
  1324.